import redis
import json
from django.db import transaction
from .models import Product, Order, OrderItem
from .exceptions import (
    InvalidOrderException,
    InsufficientStockException,
    ProductNotFoundException
)
from .redis_utils import RedisClient
import logging
import time

logger = logging.getLogger(__name__)


class OrderService:
    @staticmethod
    def process_batch_order(user_id, items):
        results = []
        for item in items:
            try:
                with transaction.atomic():
                    product = Product.objects.select_for_update().get(
                        pk=item['product_id']
                    )

                    if product.stock < item['quantity']:
                        raise InsufficientStockException(
                            f"商品 {product.name} 库存不足"
                        )

                    # 扣减库存
                    product.stock -= item['quantity']
                    product.save()

                    # 创建订单
                    order = Order.objects.create(
                        user_id=user_id,
                        status='pending'
                    )
                    OrderItem.objects.create(
                        order=order,
                        product=product,
                        quantity=item['quantity'],
                        price=product.price
                    )

                    # 更新缓存
                    RedisClient.cache_product(product)

                    results.append({
                        'product_id': product.id,
                        'success': True,
                        'order_id': order.id
                    })

            except Exception as e:
                logger.error(f"订单处理失败: {str(e)}")
                results.append({
                    'product_id': item.get('product_id'),
                    'success': False,
                    'error': str(e)
                })

        return results


class SearchService:
    @staticmethod
    def search_by_keyword(keyword):
        # 先查Redis缓存
        r = RedisClient()
        cache_key = f"search:{keyword.lower()}"
        cached = r.get(cache_key)

        if cached:
            return json.loads(cached)

        # 缓存未命中则查询数据库
        products = Product.objects.filter(
            name__icontains=keyword
        ).values('id', 'name', 'price', 'stock')[:100]

        # 写入缓存
        try:
            r.setex(cache_key, 3600, json.dumps(list(products)))
        except Exception as e:
            logger.error(f"Redis缓存写入失败: {str(e)}")

        return products

    @staticmethod
    def get_product_with_cache(product_id):
        # 先查Redis缓存
        r = RedisClient()
        cache_key = f"product:{product_id}"
        cached = r.get(cache_key)

        if cached:
            return json.loads(cached)

        # 数据库查询
        product = Product.objects.filter(pk=product_id).first()
        if not product:
            raise ProductNotFoundException()

        # 构建缓存数据
        product_data = {
            'id': product.id,
            'name': product.name,
            'price': str(product.price),
            'stock': product.stock
        }

        # 写入缓存
        try:
            r.setex(cache_key, 1800, json.dumps(product_data))
        except Exception as e:
            logger.error(f"Redis缓存写入失败: {str(e)}")

        return product_data
